home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
Libraries
/
Sherlock 2.0
/
Sherlock_DevLib
/
sl_util.c
< prev
next >
Wrap
Text File
|
1996-03-12
|
4KB
|
262 lines
/*
Sherlock utility routines.
source: sl_util.c
started: November 4, 1993.
version: March 12, 1996.
*/
#include <LIBlib.h>
#include <LIBend.h>
#include <sl.h>
#include <sl2.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#ifdef applec
#include <SegLoad.h>
#include <OSUtils.h>
#endif
/*
Abort Sherlock.
This is to be called if an error prevents Sherlock from being initialized.
Assume nothing is available that must be initialized.
*/
void
sl_abort(int beeps)
{
#if defined(THINK_C) || defined(SYMANTEC_C) || defined(__MWERKS__)
int i;
for (i = 0; i < beeps; i++) {
SysBeep(20);
}
#endif
end_abort();
}
/*
Function prototypes of internal routines.
*/
static int sl_hash (char *);
/*
Return the name on the call stack n levels back.
*/
char *
sl_callname(int n)
{
register sl_snode * sp;
if (n < 0 || (sl_level - n - 1 < 0) || sl_stack == NULL) {
return "";
}
else {
char * the_name;
sp = &sl_stack [sl_level - n - 1];
the_name = sp -> node -> name;
return (the_name[0] == '!' || the_name[0] == '+') ? the_name+1 : the_name;
}
}
/*
SL_CLEAR macro--Clear all statistics.
*/
void
sl_clear(void)
{
register int i;
register sl_node * p;
/* 5/19/92 */
if (sl_htab == NULL) {
return;
}
for (i = 0; i < SL_MAX_HASH; i++) {
for (p = sl_htab[i]; p; p = p -> next) {
p -> time = 0;
p -> time2 = 0;
p -> calls = 0;
}
}
}
/*
Check the string arguments to a tracing function.
The sl_cname global variable points to a string containing the
name of the macro responsible for invoking the check.
*/
void
sl_check(register char *s)
{
register char c;
register int i;
char *old_s;
old_s = s;
/* Check for null string. */
if (!*s) {
es("sl_check: "); es(sl_cname);
es(": null string @ "); eptr(s); enl();
sl_exit();
}
/* Skip over ! and - characters. */
if (*s == '!' || *s == '-') {
s++;
}
if (*s == '!' || *s == '-') {
s++;
}
/* 6/27/89: allow up to 31 character names. */
for (i = 0; i < 31; i++) {
c = *s++;
if (c == '\0') {
return ;
}
/* Allow only identifiers and wild cards. */
if (!isalnum(c) && c != '_' && c != '*' && c != '?') {
es("sl_check: "); es(sl_cname);
es(": bad character: "); echar(c);
es(" in "); es(old_s);
es(" @ "); eptr(s); enl();
sl_exit();
}
}
es("sl_check: "); es(sl_cname);
es(": run on argument: "); es(old_s);
es(" @ "); eptr(s); enl();
sl_exit();
}
/*
Print out n periods.
*/
void
sl_dots(n)
int n;
{
int i;
ecnl();
if (!sl_nodots) {
for(i = 0; i < n+1; i++) {
echar('.');
}
}
}
/*
Do whatever is necessary to terminate Sherlock.
*/
void
sl_exit(void)
{
#if defined(THINK_C) || defined(SYMANTEC_C) || defined(__MWERKS__)
SysBeep( 5L );
es("Press the mouse to continue...\n");
while(!Button()) {
;
}
ExitToShell();
#else
exit(1);
#endif
}
/*
Return a pointer to the node for s.
Set the global sl_cname to macro_type.
This is for internal use only.
Users should use sl_findname in macro.c.
*/
sl_node *
sl_find(char *macro_type, char *s)
{
register int i;
register sl_node *p, *q, *node;
register int hash;
/* 5/19/92 */
if (sl_htab == NULL) {
sl_abort(SL_ABORT_FIND);
}
/* Update global error string. */
if (macro_type != NULL) {
sl_cname = macro_type;
}
/* Skip over ! and - characters. */
if (*s == '!' || *s == '-') {
s++;
}
if (*s == '!' || *s == '-') {
s++;
}
/* Search the proper index table. */
hash = sl_hash(s);
p = sl_htab [hash];
if (p != NULL) {
i = strcmp(s, p -> name);
if (i == 0) {
return p;
}
}
if (p == NULL || i < 0) {
sl_check(s);
node = sl_new(s);
sl_htab [hash] = node;
node -> next = p;
return node;
}
/* Search the list for the node. */
for (q = p, p = p -> next; p; q = p, p = p -> next) {
i = strcmp(s, p -> name);
if (i == 0) {
return p;
}
else if (i < 0) {
break;
}
}
/* Not found. */
sl_check(s);
node = sl_new(s);
q -> next = node;
node -> next = p;
return node;
}
/*
Compute hash code for the string s.
*/
static int
sl_hash(register char *s)
{
register unsigned int hash = 0;
while (*s) {
hash += hash + hash + (unsigned int) *s++;
hash %= SL_MAX_HASH;
}
return (int) hash;
}